package com.yjw.demo.mybatis.common.util;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

/**
 * JSON 工具类
 * 
 * @author yinjianwei
 * @date 2017/12/15
 */
public class JsonUtils {
    /**
     * 私有化构造函数
     */
    private JsonUtils() {

    }

    /**
     * Jackson ObjectMapper
     */
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static final String DYNC_INCLUDE = "DYNC_INCLUDE";
    static final String DYNC_FILTER = "DYNC_FILTER";

    static {
        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }

    @JsonFilter(DYNC_FILTER)
    interface DynamicFilter {}

    @JsonFilter(DYNC_INCLUDE)
    interface DynamicInclude {}

    /**
     * 获取Jackson ObjectMapper
     * 
     * @return
     */
    public static ObjectMapper getInstance() {
        return OBJECT_MAPPER;
    }

    /**
     * JavaBean、Array、List、Set、Map转换为JSON字符串
     * 
     * @param obj
     * @return
     * @throws JsonProcessingException
     * @throws Exception
     */
    public static String toJSONString(Object obj) throws JsonProcessingException {
        return OBJECT_MAPPER.writeValueAsString(obj);
    }

    /**
     * JavaBean、Array、List、Set、Map转换为JSON字符串
     * 
     * @param obj 需要转换的对象
     * @param clzss 需要处理字段的真实类型
     * @param includeFields 包含字段
     * @param filterFields 过滤字段
     * @return
     * @throws JsonProcessingException
     */
    public static <T> String toJSONString(Object obj, Class<T> clzss, String includeFields, String filterFields)
        throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        if (StringUtils.isNotBlank(includeFields)) {
            objectMapper.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_INCLUDE,
                SimpleBeanPropertyFilter.filterOutAllExcept(includeFields.split(","))));
            objectMapper.addMixIn(clzss, DynamicInclude.class);
        } else if (StringUtils.isNotBlank(filterFields)) {
            objectMapper.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_FILTER,
                SimpleBeanPropertyFilter.serializeAllExcept(filterFields.split(","))));
            objectMapper.addMixIn(clzss, DynamicFilter.class);
        }
        return objectMapper.writeValueAsString(obj);
    }

    /**
     * 把JSON字符串转换为Java对象
     * 
     * @param content JSON字符串
     * @param clazz 类型
     * @return
     * @throws IOException
     * @throws JsonMappingException
     * @throws JsonParseException
     * @throws Exception
     */
    public static <T> T parseObject(String content, Class<T> clazz)
        throws JsonParseException, JsonMappingException, IOException {
        return OBJECT_MAPPER.readValue(content, clazz);
    }

    /**
     * 把JSON字符串转换为Java对象
     * 
     * @param content JSON字符串
     * @param typeReference 类型
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> T parseObject(String content, TypeReference<T> typeReference)
        throws JsonParseException, JsonMappingException, IOException {
        return OBJECT_MAPPER.readValue(content, typeReference);
    }

    /**
     * 把JSON字符串转换为Map<String, T>
     * 
     * @param content JSON字符串
     * @param clazz 类型
     * @return
     * @throws IOException
     * @throws JsonMappingException
     * @throws JsonParseException
     * @throws Exception
     */
    public static <T> Map<String, T> parseMap(String content)
        throws JsonParseException, JsonMappingException, IOException {
        return OBJECT_MAPPER.readValue(content, new TypeReference<Map<String, T>>() {});
    }

    /**
     * 把JSON字符串转换为List<T>
     * 
     * @param content JSON字符串
     * @param clazz List中数据的类型
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> List<T> parseList(String content) throws JsonParseException, JsonMappingException, IOException {
        return OBJECT_MAPPER.readValue(content, new TypeReference<List<T>>() {});
    }

    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {}

}
